home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / whati~gz.zoo / mkwhatis.c < prev    next >
C/C++ Source or Header  |  1992-09-13  |  7KB  |  366 lines

  1. /*
  2.  *    mkwhatis - read/print "SEE ALSO" or NAME section of unformatted manpage
  3.  *
  4.  *    finds .SH "SEE ALSO" or .SH NAME line and prints next line(s) until
  5.  *    either EOF or first char of line is '.'
  6.  *
  7.  *    this is a tool to help build the whatis(1) databases. the idea is
  8.  *    to feed it a list of manpages (source form). it does a reasonable
  9.  *    job, but is not perfect. you may have to do some editing...
  10.  *
  11.  *    the format for each line of the whatis databases is:
  12.  *
  13.  *    name%aliases%section%subsection%description%xrefs%keywords
  14.  *
  15.  *    name        program/routine/etc name. (required)
  16.  *    alias        if this sources another manpage or refered by another
  17.  *            name. a comma-separated list. (optional)
  18.  *    section        number [0-9nlo] (required)
  19.  *    subsection    single capital letter (optional)
  20.  *    description    what this is, ascii string (required)
  21.  *    xref        basically "SEE ALSO". a comma-separated list (optional)
  22.  *    keywords    any descriptive keywords. comma-sep list (optional)
  23.  *
  24.  *    optional fields contain only a '_' char.
  25.  *
  26.  *    here is an example:
  27.  *
  28.  *    unixmode%_%5%_%Extended Filename Standard%tcsh(1),sh(1)%TOS,MiNT,file,glob,links,shell,standard
  29.  *
  30.  *    it assumes manpage (src) that look like this:
  31.  *
  32.  *        .TH FOO 1X            <-- gives section, subsection
  33.  *        .SH NAME
  34.  *        foo \- blah blah blah        <-- gives name, desc
  35.  *        .SH DESCIPTION
  36.  *        .
  37.  *        .
  38.  *        .
  39.  *        .SH "SEE ALSO"
  40.  *        bar(1), foobar(5)        <-- gives xref
  41.  *        .SH SOMETHING  (or eof)
  42.  *
  43.  *    or
  44.  *        .TH FOO 1 LOCAL            <-- gives section, subsection
  45.  *        .
  46.  *        .
  47.  *        .
  48.  *
  49.  *    it does NOT handle sourced files (aliases), ie:
  50.  *
  51.  *        .so man1/foo.1
  52.  *
  53.  *    at a minimum, you will have to add keywords yourself.
  54.  */
  55.  
  56. static char *rcsid_mkwhatis_c = "$Id: mkwhatis.c,v 2.0 1992/09/13 05:02:44 rosenkra Exp $";
  57. /*
  58.  * $Log: mkwhatis.c,v $
  59.  * Revision 2.0  1992/09/13  05:02:44  rosenkra
  60.  * total rewrite. this if first rev of this file.
  61.  *
  62.  *
  63.  */
  64.  
  65. #include <stdio.h>
  66. #include <string.h>
  67. #include <stdlib.h>
  68.  
  69. #define EOS        '\0'
  70. #define NL        '\n'
  71. #define CR        '\r'
  72. #define TAB        '\t'
  73. #define SPC        ' '
  74. #define DOT        '.'
  75. #define DASH        '-'
  76.  
  77.  
  78. #define NAME        "NAME"
  79. #define SEE_ALSO    "SEE ALSO"
  80. #define SEE_ALSO_Q    "\"SEE ALSO"
  81.  
  82.  
  83. #define PR_NULL_FIELD    printf("%%_");
  84.  
  85.  
  86. #define B_SIZE        1024
  87.  
  88.  
  89. char    buf[B_SIZE];
  90. FILE   *stream;
  91.  
  92.  
  93. void    read_xref (void);
  94. char   *skipwhite (char *);
  95. char   *skipword (char *);
  96. char   *finddash (char *);
  97. void    kill_newline (char *);
  98.  
  99.  
  100. void main (int argc, char *argv[])
  101. {
  102.     char   *ps;
  103.     int    sec;
  104.     int    subsec;
  105.     int    got_xref = 0;
  106.     int    got_name = 0;
  107.  
  108.  
  109.  
  110.     for (argc--, argv++; argc && **argv == '-'; argc--, argv++)
  111.     {
  112.         switch (*(*argv+1))
  113.         {
  114.         default:
  115.             fprintf (stderr,
  116.                 "usage: mkwhatis [-A | -N | -S | -B] file...\n");
  117.             exit (1);
  118.         }
  119.     }
  120.  
  121.  
  122.     /*
  123.      *   args are manpage source files
  124.      */
  125.     for ( ; argc && *argv; argc--, argv++)
  126.     {
  127.         if ((stream = fopen (*argv, "r")) == (FILE *) NULL)
  128.         {
  129.             fprintf (stderr,
  130.                 "mkwhatis: could not open %s\n", *argv);
  131.             continue;
  132.         }
  133.  
  134.  
  135.         got_xref = 0;
  136.         got_name = 0;
  137.  
  138.         while (1)
  139.         {
  140.             fgets (buf, B_SIZE-1, stream);
  141.             if (feof (stream))
  142.             {
  143.                 /* if we exit loop here, things were probably
  144.                    ok, but there was no SEE ALSO. put out
  145.                    an appropriate ending... */
  146.  
  147.                 if (got_name && !got_xref)
  148.                     printf ("%%_%%_\n");
  149.                 else
  150.                     printf ("\n");
  151.  
  152.                 goto next1;            /* ERROR? */
  153.             }
  154.             kill_newline (buf);
  155.  
  156.  
  157.             /*
  158.              *   look for .TH or .SH
  159.              */
  160.             if (buf[0] != DOT)
  161.                 continue;
  162.             if (buf[1] == 'T' && buf[2] == 'H')
  163.             {
  164.                 ps = buf;
  165.  
  166.                 /* skip .TH */
  167.                 if ((ps = skipword (ps)) && *ps == EOS)
  168.                     goto next1;        /* ERROR */
  169.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  170.                     goto next1;        /* ERROR */
  171.  
  172.                 /* skip FOO */
  173.                 if ((ps = skipword (ps)) && *ps == EOS)
  174.                     goto next1;        /* ERROR */
  175.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  176.                     goto next1;        /* ERROR */
  177.  
  178.                 if (*ps)
  179.                     sec = *ps;
  180.                 else
  181.                     sec = '1';    /* assume */
  182.                 
  183.                 subsec = EOS;        /* none */
  184.  
  185.                 /* skip sect */
  186.                 if ((ps = skipword (ps)) && *ps == EOS)
  187.                     continue;
  188.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  189.                     continue;
  190.  
  191.                 if (*ps)
  192.                     subsec = *ps;
  193.                 
  194.             }
  195.             else if (buf[1] == 'S' && buf[2] == 'H')
  196.             {
  197.                 ps = buf;
  198.  
  199.                 /* skip .SH */
  200.                 if ((ps = skipword (ps)) && *ps == EOS)
  201.                     goto next1;        /* ERROR */
  202.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  203.                     goto next1;        /* ERROR */
  204.  
  205.                 if (!strncmp (ps, NAME, 4))
  206.                 {
  207.                     char *dsh;
  208.  
  209.                     fgets (buf, B_SIZE-1, stream);
  210.                     if (feof (stream))
  211.                     {
  212.                         goto next1;    /* ERROR */
  213.                     }
  214.                     kill_newline (buf);
  215.  
  216.                     ps = buf;
  217.                     
  218.                     if ((ps = finddash (ps)) && *ps == EOS)
  219.                         goto next1;    /* ERROR */
  220.                     
  221.                     /* skip past dash to desc */
  222.                     dsh = ps;
  223.                     if ((ps = skipword (ps)) && *ps == EOS)
  224.                         goto next1;    /* ERROR */
  225.                     if ((ps = skipwhite (ps)) && *ps == EOS)
  226.                         goto next1;    /* ERROR */
  227.  
  228.                     /* find end of name, going backwards
  229.                        from dash */
  230.                     if (dsh[-1] == '\\')
  231.                         dsh--;
  232.  
  233.                     while (dsh > buf
  234.                     && (dsh[-1] == SPC || dsh[-1] == TAB))
  235.                         dsh--;
  236.                     *dsh = EOS;
  237.  
  238.                     /* check for name */
  239.                     if (buf[0] == EOS)
  240.                         goto next1;    /* ERROR */
  241.  
  242.                     printf ("%s", buf);    /* name */
  243.  
  244.                     PR_NULL_FIELD;        /* alias */
  245.  
  246.                     printf ("%%%c", sec);    /* section */
  247.  
  248.                     if (subsec)        /* subsect */
  249.                         printf ("%%%c", subsec);
  250.                     else
  251.                         PR_NULL_FIELD;
  252.  
  253.                     if (ps && *ps)        /* desc */
  254.                         printf ("%%%s", ps);
  255.                     else
  256.                         PR_NULL_FIELD;
  257.  
  258.                     got_name = 1;
  259.                 }
  260.                 else if (strncmp (ps, SEE_ALSO, 8) == 0
  261.                 ||       strncmp (ps, SEE_ALSO_Q, 9) == 0)
  262.                 {
  263.                     got_xref = 1;
  264.                     printf ("%%");        /* xref */
  265.  
  266.                     read_xref ();
  267.  
  268.                     break;        /* normal exit! */
  269.                 }
  270.             }
  271.         }
  272.         if (!got_xref)
  273.             PR_NULL_FIELD;                /* xref */
  274.  
  275.         PR_NULL_FIELD;                    /* keywords */
  276.         printf ("\n");
  277. next1: ;
  278.         fclose(stream);
  279.     }
  280.     exit(0);
  281. }
  282.  
  283.  
  284.  
  285. /*------------------------------*/
  286. /*    read_xref        */
  287. /*------------------------------*/
  288. void read_xref (void)
  289. {
  290.     char   *ps;
  291.  
  292.     while (1)
  293.     {
  294.         fgets (buf, B_SIZE-1, stream);
  295.         if (feof (stream) || buf[0] == '.')
  296.             return;
  297.         kill_newline (buf);
  298.  
  299. /*        fputs (buf, stdout);*/
  300.         for (ps = buf; *ps; ps++)
  301.         {
  302.             if (*ps == SPC)
  303.                 continue;
  304.             putchar (*ps);
  305.         }
  306.     }
  307.     return;
  308. }
  309.  
  310.  
  311.  
  312. /*------------------------------*/
  313. /*    skipwhite        */
  314. /*------------------------------*/
  315. char *skipwhite (char *ps)
  316. {
  317.     while (*ps && (*ps == SPC || *ps == TAB))
  318.         ps++;
  319.     return (ps);
  320. }
  321.  
  322.  
  323.  
  324. /*------------------------------*/
  325. /*    skipword        */
  326. /*------------------------------*/
  327. char *skipword (char *ps)
  328. {
  329.     while (*ps && (*ps != SPC && *ps != TAB))
  330.         ps++;
  331.     return (ps);
  332. }
  333.  
  334.  
  335.  
  336. /*------------------------------*/
  337. /*    finddash        */
  338. /*------------------------------*/
  339. char *finddash (char *ps)
  340. {
  341.     while (*ps && *ps != DASH)
  342.         ps++;
  343.     return (ps);
  344. }
  345.  
  346.  
  347.  
  348. /*------------------------------*/
  349. /*    kill_newline        */
  350. /*------------------------------*/
  351. void kill_newline (char *ps)
  352. {
  353.     while (*ps)
  354.     {
  355.         if (*ps == NL || *ps == CR)
  356.         {
  357.             *ps = EOS;
  358.             return;
  359.         }
  360.         ps++;
  361.     }
  362.     return;
  363. }
  364.  
  365.  
  366.